﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace Cherry.Agile.RpcService
{

    ///// <summary>
    ///// 跟踪信息输出代理
    ///// </summary>
    //public delegate int TracerMessageHandler(TraceMessageContext context);


    /// <summary>
    ///          WRM.Log.TraceMessageContext Class
    /// Description:      Trace message context 
    /// Author:     赖国欣  Guoxin.lai@gmail.com
    /// Create Date: 2009-9-11
    /// Update: 
    /// 
    /// </summary>
    public class TraceMessageContext
    {
        public string User { get; set; }
        public string Message { get; set; }
        public string Category { get; set; }
        public int TimeEscape { get; set; }
    }

    /// <summary>
    ///          WRM.GlobalUtility.RuntimeTracer Class
    /// Description:      Runtime tracer 
    ///                   程序运行时跟踪
    ///                   
    /// message参数的宏定义：
    ///   %PT% -- Trace Point Time  跟踪点时间(yyyy-MM-dd HH:mm:ss)
    ///   %TE% -- Trace Point Escape(ms) 跟踪点时间偏移(毫秒值)
    /// Author:     赖国欣  Guoxin.lai@gmail.com
    /// Create Date: 2009-9-10
    /// Update: 
    /// 
    /// </summary>
    public class RuntimeTracer : ITracer,IDisposable
    {
        /// <summary>
        /// 跟踪点信息实体类
        /// </summary>
        public class TracePointInfo
        {
            /// <summary>
            /// 信息
            /// </summary>
            public string Message { get; set; }
            /// <summary>
            /// 消耗的时间长度ms
            /// </summary>
            public long TimeEsacpe { get; set; }
            /// <summary>
            /// 时间跨度(与上一个跟踪点的时间长度差)ms
            /// </summary>
            public long TimeSpan { get; set; }
            public DateTime Time { get; set; }
        }

        /// <summary>
        /// Gets or sets the watcher.
        /// </summary>
        protected Stopwatch Watcher;

        //记录上一个跟踪点消耗的时间长度ms
        private long LastTimeEsc = 0;

        /// <summary>
        /// 输出上下文信息
        /// </summary>
        protected List<TracePointInfo> TracePointList { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="RuntimeTracer"/> class.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="category">The category.</param>
        /// <param name="message">The message.</param>
        protected RuntimeTracer( string user, string category)
        {
            Watcher = Stopwatch.StartNew();
        }

        /// <summary>
        /// Start an instance of tracer.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="category">The category.</param>
        /// <param name="message">
        /// message输出信息
        /// message参数的宏定义：
        ///   %PT% -- Trace Point Time  跟踪点时间(yyyy-MM-dd HH:mm:ss)
        ///   %TE% -- Trace Point Escape(ms) 跟踪点时间偏移(毫秒值)
        /// </param>
        /// <returns></returns>
        public static RuntimeTracer Start( string user, string category, string message)
        {
            RuntimeTracer tracer = new RuntimeTracer(user,category);
            tracer.AddTracePoint(message);
            return tracer;
        }

        /// <summary>
        /// Start an instance of tracer.
        /// </summary>
        /// <param name="message">
        /// message输出信息
        /// message参数的宏定义：
        ///   %PT% -- Trace Point Time  跟踪点时间(yyyy-MM-dd HH:mm:ss)
        ///   %TE% -- Trace Point Time Escape(ms) 跟踪点时间偏移(毫秒值)
        ///   %TS% -- Trace Point Time Span(ms) 距上一个跟踪点的时间跨度(毫秒值)
        /// </param>
        /// <returns></returns>
        public static RuntimeTracer Start( string message)
        {
            return Start(string.Empty, string.Empty, message);
        }


        /// <summary>
        /// Adds the trace point.
        /// 加入一个跟踪点
        /// </summary>
        /// <param name="message">
        /// message输出信息
        /// message参数的宏定义：
        ///   %PT% -- Trace Point Time  跟踪点时间(yyyy-MM-dd HH:mm:ss)
        ///   %TE% -- Trace Point Time Escape(ms) 跟踪点时间偏移(毫秒值)
        ///   %TS% -- Trace Point Time Span(ms) 距上一个跟踪点的时间跨度(毫秒值)
        /// </param>
        public void AddTracePoint(string message)
        {
            long timeEsc = 0;
            if (Watcher != null)
            {
                timeEsc = Watcher.ElapsedMilliseconds;
            }
            TracePointInfo tp = new TracePointInfo()
            {
                TimeEsacpe = timeEsc,
                Message = message,
                Time = DateTime.Now,
                TimeSpan=timeEsc-LastTimeEsc,
            };
            LastTimeEsc = timeEsc;
            if(TracePointList==null)
                TracePointList = new List<TracePointInfo>();
            TracePointList.Add(tp);
        }

        /// <summary>
        /// Stops the tracer and call messagehandler.
        /// 停止跟踪，并将信息通过代理输出
        /// </summary>
        /// <param name="timeEscapeThreshold">The time escape threshold.信息输出的时间阀值</param>
        /// <param name="message">
        /// message输出信息
        /// message参数的宏定义：
        ///   %PT% -- Trace Point Time  跟踪点时间(yyyy-MM-dd HH:mm:ss)
        ///   %TE% -- Trace Point Time Escape(ms) 跟踪点时间偏移(毫秒值)
        ///   %TS% -- Trace Point Time Span(ms) 距上一个跟踪点的时间跨度(毫秒值)
        /// </param>
        public string Stop(int timeEscapeThreshold, string message)
        {
            if (timeEscapeThreshold > 0 && Watcher.ElapsedMilliseconds < timeEscapeThreshold)
                return string.Empty;
             return Stop(message);
        }

        /// <summary>
        /// 停止跟踪，并将(默认的)信息通过代理输出
        /// 默认结束信息为：%PT% End. time escape:%TE%ms
        /// </summary>
        /// <returns></returns>
        public string Stop()
        {
            return Stop("%PT% End. Time escape:%TE%ms");
        }

        /// <summary>
        /// Stops the tracer and call messagehandler.
        /// 停止跟踪，并将信息参数输出
        /// </summary>
        /// <param name="message">message输出信息
        /// message参数的宏定义：
        /// %PT% -- Trace Point Time  跟踪点时间(yyyy-MM-dd HH:mm:ss)
        /// %TE% -- Trace Point Time Escape(ms) 跟踪点时间偏移(毫秒值)
        /// %TS% -- Trace Point Time Span(ms) 距上一个跟踪点的时间跨度(毫秒值)</param>
        /// <returns></returns>
        public string Stop(string message)
        {
            AddTracePoint(message);
            StringBuilder sb = new StringBuilder(1024);
            foreach (TracePointInfo tp in TracePointList)
            {
                string s = tp.Message.Replace("%PT%", tp.Time.ToString("yyyy-MM-dd HH:mm:ss"))
                                     .Replace("%TE%", tp.TimeEsacpe.ToString("#,#", System.Globalization.CultureInfo.InvariantCulture))
                                     .Replace("%TS%", tp.TimeSpan.ToString("#,#", System.Globalization.CultureInfo.InvariantCulture));
                sb.AppendLine(s);
            }
            return sb.ToString();
        }

        public void Dispose()
        {
            if (Watcher != null)
            {
                Watcher.Stop();
                Watcher = null;
            }
        }
    }
}
